import { BaseData } from '../base-data';
import { PageLink } from '../page/page-link';
import { Direction, SortOrder } from '../page/sort-order';
import { Observable, of } from 'rxjs';
import { DatePipe } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { Type } from '@angular/core';
import { ITableComponent } from './table-component.models';
import { IItemDetailsPageComponent, ItemAction } from './table-data.models';
import { PageData, emptyPageData } from '../page/page-data';
import { TableHeaderComponent } from '@shared/components/table/table-header.component';
import { TableDataSource } from './table-datasource';
import { ItemComponent } from '@shared/components/table/item.component';

// ========== 函数类型定义 ==========

export type ItemBooleanFunction<T extends BaseData> = (item: T) => boolean; // 行级布尔判断
export type ItemStringFunction<T extends BaseData> = (item: T) => string; // 行级文本
export type ItemVoidFunction<T extends BaseData> = (item: T) => void; // 行级副作用
export type ItemIdsVoidFunction<T extends BaseData> = (ids: string[]) => void; // 批量副作用
export type TableCountStringFunction = (count: number) => string; // 计数转文本

export type TableTwoWayOperation<T extends BaseData> = (item: T, originalItem?: T) => Observable<T>; // 保存/更新
export type TableByIdOperation<T extends BaseData> = (id: string) => Observable<T>; // 通过ID获取
export type TableIdOneWayOperation = (id: string) => Observable<unknown>; // 通过ID副作用
export type TableRowClickFunction<T extends BaseData> = (event: Event, item: T) => boolean; // 行点击处理
export type CreateItemOperation<T extends BaseData> = () => Observable<T>; // 创建项操作：返回新建后的数据
export type ItemActionFunction<T extends BaseData> = (action: ItemAction<T>) => boolean; // 动作分发

export type CellContentFunction<T extends BaseData> = (item: T, key: string) => string; // 单元格内容
export type CellTooltipFunction<T extends BaseData> = (item: T, key: string) => string | undefined; // 单元格提示
export type HeaderCellStyleFunction = (key: string) => Record<string, unknown>; // 表头样式
export type CellStyleFunction<T extends BaseData> = (item: T, key: string) => Record<string, unknown>; // 单元格样式
export type CopyCellContent<T extends BaseData> = (item: T, key: string, length: number) => Record<string, unknown>; // 复制内容

// ========== 操作描述符 ==========

export enum CellActionDescriptorType {
  DEFAULT = 'DEFAULT',
  COPY_BUTTON = 'COPY_BUTTON'
}

export interface CellActionDescriptor<T extends BaseData> {
  name: string;
  nameFunction?: (item: T) => string;
  icon?: string;
  iconFunction?: (item: T) => string;
  style?: Record<string, unknown>;
  isEnabled: (item: T) => boolean;
  onAction: ($event: MouseEvent, item: T) => unknown;
  type?: CellActionDescriptorType;
}

export interface GroupActionDescriptor<T extends BaseData> {
  name: string;
  icon: string;
  isEnabled: boolean;
  onAction: ($event: MouseEvent, items: T[]) => void;
}

export interface HeaderActionDescriptor {
  name: string;
  icon: string;
  isEnabled: () => boolean;
  onAction: ($event: MouseEvent) => void;
}

// ========== 列类型定义 ==========

export type TableColumnType = 'content' | 'action' | 'link' | 'chips';

export class BaseTableColumn<T extends BaseData> {
  constructor(
    public type: TableColumnType,
    public key: string,
    public title: string,
    public width: string = '0px',
    public sortable: boolean = true,
    public ignoreTranslate: boolean = false,
    public mobileHide: boolean = false
  ) {}
}

export class TableColumn<T extends BaseData> extends BaseTableColumn<T> {
  constructor(
    public override key: string,
    public override title: string,
    public override width: string = '0px',
    public cellContentFunction: CellContentFunction<T> = (item, property) => {
      const value = (item as Record<string, unknown>)[property];
      return value ? String(value) : '';
    },
    public cellStyleFunction: CellStyleFunction<T> = () => ({}),
    public override sortable: boolean = true,
    public headerCellStyleFunction: HeaderCellStyleFunction = () => ({}),
    public cellTooltipFunction: CellTooltipFunction<T> = () => undefined,
    public isNumberColumn: boolean = false,
    public actionCell: CellActionDescriptor<T> | null = null
  ) {
    super('content', key, title, width, sortable);
  }
}

export class ActionTableColumn<T extends BaseData> extends BaseTableColumn<T> {
  constructor(
    public override key: string,
    public override title: string,
    public actionDescriptor: CellActionDescriptor<T>,
    public override width: string = '0px'
  ) {
    super('action', key, title, width, false);
  }
}

export class LinkTableColumn<T extends BaseData> extends BaseTableColumn<T> {
  constructor(
    public override key: string,
    public override title: string,
    public override width: string = '0px',
    public cellContentFunction: CellContentFunction<T> = (item, property) => {
      const value = (item as Record<string, unknown>)[property];
      return value ? String(value) : '';
    },
    public itemURL: (item: T) => string,
    public override sortable: boolean = true,
    public cellStyleFunction: CellStyleFunction<T> = () => ({}),
    public headerCellStyleFunction: HeaderCellStyleFunction = () => ({}),
    public cellTooltipFunction: CellTooltipFunction<T> = () => undefined,
    public actionCell: CellActionDescriptor<T> | null = null
  ) {
    super('link', key, title, width, sortable);
  }
}

export class DateTableColumn<T extends BaseData> extends TableColumn<T> {
  constructor(
    key: string,
    title: string,
    datePipe: DatePipe,
    width: string = '0px',
    dateFormat: string = 'yyyy-MM-dd HH:mm:ss',
    cellStyleFunction: CellStyleFunction<T> = () => ({})
  ) {
    super(
      key,
      title,
      width,
      (item, property) => {
        const value = (item as Record<string, unknown>)[property];
        return datePipe.transform(value as string | number | Date, dateFormat) || '';
      },
      cellStyleFunction
    );
  }
}

export class ChipsTableColumn<T extends BaseData> extends BaseTableColumn<T> {
  constructor(
    public override key: string,
    public override title: string,
    public override width: string = '0px',
    public itemURL?: (item: T) => string
  ) {
    super('chips', key, title, width, false);
  }
}

export type TableColumnDef<T extends BaseData> =
  | TableColumn<T>
  | ActionTableColumn<T>
  | LinkTableColumn<T>
  | ChipsTableColumn<T>;

// ========== 表格配置类 ==========

export class TableConfig<T extends BaseData, P extends PageLink = PageLink, L extends BaseData = T> {
  constructor() {}

  // 引用与上下文
  private table: ITableComponent<T> | null = null; // 表格实例引用
  private detailsPage: IItemDetailsPageComponent | null = null; // 详情页实例引用
  componentsData: unknown = null; // 组件数据透传

  // 基础配置
  tableTitle = ''; // 表格标题
  actionsColumnTitle: string | null = null; // 操作列标题
  headerComponent: Type<TableHeaderComponent<T, P, L>> | null = null; // 头部组件

  // 初始化与加载
  loadDataOnInit = true; // 初始化加载数据
  onLoadAction: ((route: ActivatedRoute) => void) | null = null; // 路由加载回调

  // 显示控制
  selectionEnabled = true; // 启用选择
  searchEnabled = true; // 启用搜索
  displayPagination = true; // 显示分页
  pageMode = true; // 分页模式，控制是否将分页/排序/搜索状态同步到 URL：true = 同步到 URL（支持刷新页面恢复状态、分享链接），false = 仅内存状态（不写入 URL，刷新后丢失）
  defaultPageSize = 10; // 默认页大小
  defaultSortOrder: SortOrder = { property: 'createdTime', direction: Direction.DESC }; // 默认排序
  rowPointer = false; // 行鼠标指针样式

  // 时间分页
  useTimePageLink = false; // 启用时间分页
  forAllTimeEnabled = false; // 全时段开关
  defaultTimewindowInterval: unknown = null; // 默认时间窗口

  // 详情面板
  detailsPanelEnabled = true; // 启用详情面板
  detailsReadonly: ItemBooleanFunction<T> = () => false; // 详情是否只读
  hideDetailsTabsOnEdit = true; // 编辑时隐藏详情页签

  // 新增功能
  addEnabled = true; // 启用新增
  addAsTextButton = false; // 新增按钮为文本样式
  addDialogStyle: Record<string, unknown> = {}; // 新增对话框样式
  addItem: CreateItemOperation<T> | null = null; // 新增项操作
  addDialogComponent: Type<unknown> | null = null; // 新增对话框组件
  addActionDescriptors: Array<HeaderActionDescriptor> = []; // 额外新增动作描述符

  // 删除功能
  itemsDeleteEnabled = true; // 启用批量删除
  deleteEnabled: ItemBooleanFunction<T | L> = () => true; // 行是否可删除
  deleteItem: TableIdOneWayOperation = () => of(null); // 按ID删除操作
  deleteItemTitle: ItemStringFunction<L> = () => ''; // 删除对话框标题
  deleteItemContent: ItemStringFunction<L> = () => ''; // 删除对话框内容
  deleteItemsTitle: TableCountStringFunction = () => ''; // 批量删除对话框标题
  deleteItemsContent: TableCountStringFunction = () => ''; // 批量删除对话框内容

  // 列与动作
  columns: Array<TableColumnDef<L>> = []; // 列定义
  cellActionDescriptors: Array<CellActionDescriptor<L>> = []; // 行级动作
  groupActionDescriptors: Array<GroupActionDescriptor<L>> = []; // 批量动作
  headerActionDescriptors: Array<HeaderActionDescriptor> = []; // 表头动作

  // 数据源
  itemsFetchFunction: ((pageLink: P) => Observable<PageData<L>>) = () => of(emptyPageData<L>()); // 分页拉取函数
  dataSource: ((dataLoadedFunction: (col?: number, row?: number) => void) => TableDataSource<L, P>) = 
    (dataLoadedFunction: (col?: number, row?: number) => void) =>
      new TableDataSource<L, P>(this.itemsFetchFunction, this.itemSelectionEnabled, dataLoadedFunction); // 数据源工厂

  // CRUD 操作
  loadItem: TableByIdOperation<T | L> = () => of(); // 按ID加载项
  saveItem: TableTwoWayOperation<T> = (item) => of(item); // 保存/更新项

  // 权限与可见性
  itemSelectionEnabled: ItemBooleanFunction<L> = () => true; // 行是否可选

  // 交互与回调
  onItemAction: ItemActionFunction<T> = () => false; // 行级动作分发
  handleRowClick: TableRowClickFunction<L> = () => false; // 行点击处理
  itemTitle: ItemStringFunction<T> = (item) => item?.name || ''; // 详情面板标题文案
  itemAdded: ItemVoidFunction<T> = () => {}; // 新增项后回调
  itemUpdated: ItemVoidFunction<T> = () => {}; // 更新项后回调
  itemsDeleted: ItemIdsVoidFunction<T> = () => {}; // 删除项后回调

  // 扩展配置
  itemComponent: Type<ItemComponent<T, P, L>>; // 表单组件
  itemType: unknown = null; // 项类型（对应 entityType）
  itemTranslations: unknown = null; // 项翻译（对应 entityTranslations）
  itemResources: unknown = null; // 项资源（对应 entityResources）
  itemTabsComponent: Type<unknown> | null = null; // 项标签页组件（对应 entityTabsComponent）

  getTable(): unknown {
    return this.table;
  }

  setTable(table: ITableComponent<T>): void {
    this.table = table;
    this.detailsPage = null;
  }

  getDetailsPage(): IItemDetailsPageComponent | null {
    return this.detailsPage;
  }

  setDetailsPage(detailsPage: IItemDetailsPageComponent): void {
    this.detailsPage = detailsPage;
    this.table = null;
  }

  updateData(closeDetails = false) {
    if (this.table) {
      this.table.updateData(closeDetails);
    } else if (this.detailsPage) {
      this.detailsPage.reload();
    }
  }

  toggleDetails($event: Event, item: T): void {
    if (this.table) {
      this.table.toggleDetails($event, item);
    }
  }

  isDetailsOpen(): boolean {
    if (this.table) {
      return this.table.isDetailsOpen;
    } else {
      return false;
    }
  }

  getActivatedRoute(): ActivatedRoute | null {
    if (this.table) {
      return this.table.route;
    } else {
      return null;
    }
  }
}

export const checkBoxCell = (value: boolean): string =>
  `<mat-icon class="material-icons mat-icon">${value ? 'check_box' : 'check_box_outline_blank'}</mat-icon>`;

